/***************************************************************************
 *   Copyright (C) 2009 by Jason Power                                     *
 *   power.jg@gmail.com                                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include <Python.h>
#include <QApplication>
#include <string>
#include <iostream>
#include <openbabel/mol.h>
#include <openbabel/obconversion.h>

#include <time.h>

#include <molsketch/molecule.h>

#include "mainwindow.h"
#include "origindbconvert.h"

using namespace Molsketch;

static PyObject* callback = NULL;
static bool running = false;


std::string convertToFile(OpenBabel::OBMol* mol)
{
	OpenBabel::OBConversion conv;

	conv.SetOutFormat("mol");
	std::string molfile = conv.WriteString(mol);
	return molfile;
}

OpenBabel::OBMol* convertFromFile(std::string molfile)
{
	OpenBabel::OBConversion conv;

	conv.SetInFormat("mol");

	OpenBabel::OBMol* mol = new OpenBabel::OBMol();

	conv.ReadString(mol, molfile);

	return mol;
}


void molsketch_return(MainWindow* main) {
	
	OpenBabel::OBMol mol = convertToMol(main->getScene());

	PyObject* obj;
	if (mol.NumAtoms()==0 || !main->getRet())
	{
		obj = Py_BuildValue("(i)", 0);
	}
	else
	{
		std::string molfile = convertToFile(&mol);
		obj = Py_BuildValue("(s)", molfile.data());
	}

	PyGILState_STATE state;
	state = PyGILState_Ensure();
	
	if (callback) {
		PyEval_CallObject(callback, obj);
	}

	Py_DECREF(obj);
	PyGILState_Release(state);

	running = false;

}


static PyObject* molsketch_run(PyObject *self, PyObject* args)
{
	if (running){
		Py_INCREF(Py_None);
		return Py_None;
	}

	
	char * cp = NULL;
	char ** argv = &cp;

	const char* pymol = "\0";
	int length;

	PyObject* temp;

	int argc = 0;
	
	if ( !PyArg_ParseTuple(args, "O|s", &temp, &pymol))
		return NULL;
	if (!PyCallable_Check(temp)){
		PyErr_SetString(PyExc_TypeError, "parameter 1 must be callable");
		return NULL;
	}
	Py_XINCREF(temp);
	Py_XDECREF(callback);
	callback = temp;

	MainWindow* window;

	OpenBabel::OBMol* obmol;

	if (pymol!=NULL){
		std::string molfile(pymol);
		obmol = convertFromFile(molfile);
	}
	
	if (obmol->NumAtoms()>0){
		Molsketch::Molecule* molecule = convertFromMol(*obmol);
		window = new MainWindow(molecule);
	}
	else{
		window = new MainWindow();
	}
	
	window->show();

	running = true;

	Py_INCREF(Py_None);
	return Py_None;
}



static PyMethodDef MolsketchMethods[] = {
	{"run",  molsketch_run, METH_VARARGS,
	"Run the molsketch program.\nMUST HAVE A QT APPLICATION LOOP RUNNING!"},
	{NULL, NULL, 0, NULL}        /* Sentinel */
};

PyMODINIT_FUNC initmolsketch(void)
{
	(void) Py_InitModule("molsketch", MolsketchMethods);
}

